import ExcelLibData from "./ExcelLibData";
import ExcelLibReader from "./ExcelLibReader";

export default class ExcelLib {

    /** 事件：表格定义文件Definition下载完毕 
     * onLibDefinitionDownloaded(): void
     */
    public static EVENT_LIB_DEFINITION_DOWNLOADED: string = "EVENT_LIB_DEFINITION_DOWNLOADED";
    /** 事件：表格定义文件Definition解析加载完毕 
     * onLibDefinitionCompleted()
     */
    public static EVENT_LIB_DEFINITION_COMPLETED: string = "EVENT_LIB_DEFINITION_COMPLETED";

    /** 事件：表格开始加载 
     * onLibLoadStart(loadList: Array<ExcelLibDefinition>, count: number): void
     */
    public static EVENT_LIB_LOAD_START: string = "EVENT_LIB_LOAD_START";
    /** 事件：表格全部读取开始
     * onLibLoadAllStart(loadList: Array<ExcelLibDefinition>, count: number):void
     */
    public static EVENT_LIB_LOAD_ALL_START: string = "EVENT_LIB_LOAD_ALL_START";
    /** 事件：表格按组读取开始
     * onLibLoadGroupStart(loadList: Array<ExcelLibDefinition>, count: number)
     */
    public static EVENT_LIB_LOAD_GROUP_START: string = "EVENT_LIB_LOAD_GROUP_START";    
    /** 事件：表格下载完毕
     * onLibLoadDownloaded(loadList: Array<ExcelLibDefinition>, isSuccess: boolean)
     */
    public static EVENT_LIB_LOAD_DOWNLOADED: string = "EVENT_LIB_LOAD_DOWNLOADED";
    /** 事件：表格解析加载完毕
     * onLibLoadCompleted(dataFullName: string, table: any): void
     */
    public static EVENT_LIB_LOAD_COMPLETED: string = "EVENT_LIB_LOAD_COMPLETED";
    /** 事件：表格加载失败
     * onLibLoadFail(dataFullName: string): void
     */
    public static EVENT_LIB_LOAD_FAIL: string = "EVENT_LIB_LOAD_FAIL";

    /** 事件：表格全部读取进度
     * onLibLoadProcess(process:number): void
     */
    public static EVENT_LIB_LOAD_PROCESS: string = "EVENT_LIB_LOAD_ALL_PROCESS";
    /** 事件：表格全部读取完毕
     * onLibLoadAllCompleted(loadList: Array<ExcelLibDefinition>, isAllSuccess: boolean):void
     */
    public static EVENT_LIB_LOAD_ALL_COMPLETED: string = "EVENT_LIB_LOAD_ALL_COMPLETED";

    /**
     * 单例，volatile禁止指令重排
     * (防止多线程时非创建线程抢占到cpu，然后发现instance!=null，然后直接返回使用，就会发现instance为空，就会出现异常。)
     */
    private static instance: ExcelLib = null;

    /**
     * 获取单例 (DCL模式)
     * @return
     */
    public static getInstance(): ExcelLib {
        //双端检锁机制：DCL(Double Check Lock)
        //第一层检查是为了创建后访问不需要线程同步，减少阻塞
        if (ExcelLib.instance == null) {
            ExcelLib.instance = new ExcelLib();
        }
        return ExcelLib.instance;
    }

    private libData: ExcelLibData;
    private libReader: ExcelLibReader;
    /**
     * 是否正常读入配置文件
     */
    private loadedDefinition: boolean = false;

    constructor() {
        console.log("创建了一个ExcelLib")
        this.libData = new ExcelLibData();
        this.libReader = new ExcelLibReader(this.libData);
    }
    
    public reloadDefinition() {
        let handler:Handler = Laya.Handler.create(this, this.onLibDefinitionCompleted)
        this.libReader.loadDefinition(handler);        
    }

    /**
     * 配置从配置服务器下载表
     * @param serverHost 服务器地址
     */
    public setLoadFromConfigServer(serverHost:string) {
        this.libReader.setLoadFromConfigServer(serverHost);
    }

    /**
     * 配置从资源服务器下载表     
     */
     public setLoadFromResServer() {
        this.libReader.setLoadFromResServer();
    }

    /**
     * 根据表索引名字加载文件
     * @param dataFullName 
     * @returns 
     */
    public loadFromFileByName(dataFullName: string, isLoadRelations: boolean = false) {
        this.getLibReader().loadFromFileByName(dataFullName, isLoadRelations);
    }

    public loadAllData(): boolean {
        return this.getLibReader().loadAllData();
    }

    public loadFromGroup(gruopName: string): number {
        return this.getLibReader().loadFromGroup(gruopName);
    }

    public getLibReader(): ExcelLibReader {
        return this.libReader;
    }

    public data(): ExcelLibData {
        return this.libData;
    }

    /**
     * 解析定义文件_definition.json完毕
     */
    private onLibDefinitionCompleted(result:boolean): void{
        ExcelLib.getInstance().setLoadedDefinition(result);
    }

    /**
     * 
     * @returns 
     */
    public isLoadedDefinition(): boolean{
        return this.loadedDefinition;
    }

    public setLoadedDefinition(state: boolean): void{
        this.loadedDefinition = state;
    }

}